package com.github.bobjoy.java.thread.concurrent;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Java使用代码模拟高并发操作
 * https://www.toutiao.com/i6548943938697298439/
 */
public class CountDownLatchDemo {

    // 请求总数
    private int clientTotal = 5000;
    // 并发线程总数
    private int threadTotal = 200;

    private int count1 = 0;
    private AtomicInteger count2 = new AtomicInteger(0);

    private void add1() {
        count1++;
    }

    private void add2() {
        count2.incrementAndGet();
    }

    private void mockConcurrent() throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();

        // 信号量，用于控制并发的线程数
        Semaphore semaphore = new Semaphore(threadTotal);

        // 闭锁，实现计数器递减
        CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i=0; i<clientTotal; i++) {
            executorService.execute(() -> {
                try {

                    // 获取执行许可
                    semaphore.acquire();
                    add1();
                    add2();

                    // 释放执行许可
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // 闭锁减一
                countDownLatch.countDown();
            });
        }

        // 线程阻塞，直至闭锁计数器为0
        countDownLatch.await();
        executorService.shutdown();
        System.out.println("count1: " + count1);
        System.out.println("count2: " + count2.get());

        // 恢复数值
        count1 = 0;
        count2.set(0);
    }

    @Test
    public void test() throws InterruptedException {
        for (int i=0; i<10; i++) {
            mockConcurrent();
        }
    }
}
